package com.pan.note.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pan.note.enumerate.CodeEnum;
import com.pan.note.enumerate.FileEnum;
import com.pan.note.enumerate.MsgEnum;
import com.pan.note.dao.ChatInfoDao;
import com.pan.note.dao.NoteDao;
import com.pan.note.dao.NoteFileDao;
import com.pan.note.mapper.ChatInfoMapper;
import com.pan.note.mapper.NoteFileMapper;
import com.pan.note.mapper.NoteMapper;
import com.pan.note.service.LoginService;
import com.pan.note.service.NoteService;
import com.pan.note.vo.ImgResponseData;
import com.pan.note.util.ListSortUtil;
import com.pan.note.vo.ChatMsgVo;
import com.pan.note.vo.NotePullVo;
import com.pan.note.vo.NoteUploadVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 说说上传查看相关实现类实现类
 */
@Transactional
@Service
@Slf4j
public class NoteServiceImpl implements NoteService {

    @Autowired
    private NoteFileMapper noteFileMapper;

    @Autowired
    private NoteMapper noteMapper;

    @Autowired
    private ChatInfoMapper chatInfoMapper;

    @Autowired
    private LoginService loginService;

    /**
     * 保存说说图片内容
     * @param file 说说的图片
     * @return 返回保存结果，照片id值
     */
    @Override
    public ImgResponseData saveImg(MultipartFile file) {
        //非空判断
        if (file.isEmpty())
            return null;
        //定义变量
        String originalFilename;
        String fileName;
        String fileId;
        NoteFileDao noteFileDto = new NoteFileDao();
        //获取原文件名和要保存的uuid
        originalFilename = file.getOriginalFilename();
        //获取文件类型
        String fileType = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
        fileId = UUID.randomUUID().toString();
        fileName = UUID.randomUUID() + "." + fileType;
        //在硬盘中创建文件
        File packageFile = new File(FileEnum.FILE_UPLOAD_PATH.getMsg());
        if (!packageFile.exists()) {
            packageFile.mkdir();
        }
        File targetFile = new File(FileEnum.FILE_UPLOAD_PATH.getMsg() + "/" + fileName);
        try {
            //将文件写入目标文件夹
            file.transferTo(targetFile);
            //完善dto，存入数据库
            noteFileDto.setId(fileId);
            noteFileDto.setNoteFileName(fileName);
            noteFileDto.setNoteFileType(fileType);
            //将文件信息存入数据库
            noteFileMapper.insert(noteFileDto);
            //将文件的id返回给前端，前端拿到这些id后存入说说中
            log.info("文件保存成功");
            return new ImgResponseData(CodeEnum.SUCCESS.getCode(), MsgEnum.SUCCESS.getMsg(),fileId,new Date());
        } catch (IOException e) {
            log.error("文件保存抛出异常{}",e.toString());
            e.printStackTrace();
            return new ImgResponseData(CodeEnum.ERROR.getCode(), MsgEnum.ERROR.getMsg(),null,new Date());
        }
    }

    /**
     * 保存说说内容和图片id
     * @return 保存结果
     * @param noteUploadVo 前端传入参数
     */
    @Override
    public String saveNote(NoteUploadVo noteUploadVo) {
        // 将说说内容入库
        NoteDao noteDto = new NoteDao();
        String msgId = UUID.randomUUID().toString();
        noteDto.setId(msgId);
        noteDto.setNoteMsg(noteUploadVo.getNoteMsg());
        noteDto.setNoteUserId(noteUploadVo.getUserId());
        noteDto.setNoteUserName(noteUploadVo.getUserName());
        noteDto.setNotePermission("0");
        noteMapper.insert(noteDto);
        // 循环说说携带的图片id，存入对应id的图片库中，让其关联对应说说
        String[] fileIds = noteUploadVo.getFileIds();
        // 如果图片id为空，则证明没有图片，直接退出
        if (fileIds.length != 0){
            for (String fileId : fileIds) {
                // 根据id查询说说图片
                NoteFileDao noteFileDto = noteFileMapper.selectById(fileId);
                // 将说说id存入
                noteFileDto.setNoteFileId(msgId);
                // 重新保存
                noteFileMapper.updateById(noteFileDto);
            }
            log.info("保存说说主体成功");
        }
        return "保存说说成功";
    }

    /**
     * 获取说说内容
     * @return 说说内容列表
     */
    @Override
    public List<NotePullVo> pullNote() {
        List<NotePullVo> notePullVos = new ArrayList<>();
        //查询说说
        List<NoteDao> noteDtos = noteMapper.selectList(null);
        noteDtos.forEach(noteDto -> {
            NotePullVo notePullVo = new NotePullVo();
            List<String> noteFiles = new ArrayList<>();
            notePullVo.setUserId(noteDto.getNoteUserId());
            notePullVo.setUserName(noteDto.getNoteUserName());
            notePullVo.setNoteMsg(noteDto.getNoteMsg());
            notePullVo.setTime(noteDto.getCreateTime());
            //根据说说id查询说说附件
            QueryWrapper<NoteFileDao> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("note_file_id",noteDto.getId());
            List<NoteFileDao> noteFileDtos = noteFileMapper.selectList(queryWrapper);
            //找到图片后拼接图片链接
            noteFileDtos.forEach(noteFileDto -> {
                String noteFileUrl = "";
                noteFileUrl = FileEnum.FILE_DOWNLOAD_PATH.getMsg() + noteFileDto.getNoteFileName();
                noteFiles.add(noteFileUrl);
            });
            //将拼接的链接存入要返回的结果中
            notePullVo.setFiles(noteFiles);
            //将完整信息存入返回结果list中
            notePullVos.add(notePullVo);
        });
        ListSortUtil.ListSortNotes(notePullVos);
        log.info("获取说说主体成功");
        return notePullVos;
    }

    /**
     * 拉取聊天记录
     * @param sender 发送人
     * @param receiver 接收人
     * @return 消息记录
     */
    @Override
    public List<ChatMsgVo> pullChatMsg(String sender, String receiver) {
        List<ChatMsgVo> result = new ArrayList<>();
        // 获取发送信息双方的用户名，避免在下面多次重复获取
        String senderStr = loginService.getUserName(sender);
        String receiverStr = loginService.getUserName(receiver);
        QueryWrapper<ChatInfoDao> queryWrapper1 = new QueryWrapper<>();
        QueryWrapper<ChatInfoDao> queryWrapper2 = new QueryWrapper<>();
        queryWrapper1.eq("sender",sender);
        queryWrapper1.eq("receiver",receiver);
        queryWrapper1.last("limit 5");
        // 来自我发给对方的信息
        List<ChatInfoDao> chatInfosFromMe = chatInfoMapper.selectList(queryWrapper1);
        // 来自对方发给我的信息
        queryWrapper2.eq("sender",receiver);
        queryWrapper2.eq("receiver",sender);
        queryWrapper2.last("limit 5");
        List<ChatInfoDao> chatInfoFromHe = chatInfoMapper.selectList(queryWrapper2);
        chatInfosFromMe.forEach(me -> {
            ChatMsgVo chatMsgVo = new ChatMsgVo();
            chatMsgVo.setSenderName(senderStr);
            chatMsgVo.setReceiverName(receiverStr);
            chatMsgVo.setNoteMsg(me.getChatInfo());
            chatMsgVo.setReceiver(me.getReceiver());
            chatMsgVo.setSender(me.getSender());
            chatMsgVo.setTime(me.getCreateTime());
            result.add(chatMsgVo);
        });
        chatInfoFromHe.forEach(me -> {
            ChatMsgVo chatMsgVo = new ChatMsgVo();
            chatMsgVo.setSenderName(receiverStr);
            chatMsgVo.setReceiverName(senderStr);
            chatMsgVo.setNoteMsg(me.getChatInfo());
            chatMsgVo.setReceiver(me.getReceiver());
            chatMsgVo.setSender(me.getSender());
            chatMsgVo.setTime(me.getCreateTime());
            result.add(chatMsgVo);
        });
        log.info("拉取聊天记录成功");
        ListSortUtil.ListSort(result);
        // 还要更新消息状态，将上面拿到的消息改为已读状态，然后更新数据库
        chatInfosFromMe.forEach(f -> f.setChatCheck(true));
        chatInfoFromHe.forEach(f -> f.setChatCheck(true));
        chatInfosFromMe.forEach(dto -> {
            chatInfoMapper.updateById(dto);
        });
        chatInfoFromHe.forEach(dto -> {
            chatInfoMapper.updateById(dto);
        });
        log.info("修改已读记录成功");
        return result;
    }
}
